package com.cysyz.mylib.freemarker;

import java.io.*;
import java.util.HashMap;
import java.util.Map;

import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;

public class FreeMarkerSupportTool {
	private Configuration cfg = new Configuration();
	private String directory;
	private String baseOutputPath;
	@SuppressWarnings("rawtypes")
	private Class clazzForLoadingTemplate;
	private String pathPrefix;
	
	/**
	 * 
	 * @param clazzForLoadingTemplate
	 * @param pathPrefix
	 * @param baseOutputPath 生成的文件的物理
	 */
	public FreeMarkerSupportTool(Class clazzForLoadingTemplate, String pathPrefix, String baseOutputPath) {
		this.clazzForLoadingTemplate = clazzForLoadingTemplate;
		this.pathPrefix = pathPrefix;
		this.baseOutputPath = baseOutputPath;
	}

	/**
	 * 
	 * @param directory 储存模板文件的目录
	 * @param baseOutputPath 如果设置了此变量，那么在调用generate方法时会在outputPath的前面加上此变量的值
	 */
	public FreeMarkerSupportTool(String directory, String baseOutputPath, boolean isProjectBasePath) {
		super();
		if (isProjectBasePath) {
			this.directory = this.getClass().getResource(directory).getFile();
		} else {
			this.directory = directory;
		}
		this.baseOutputPath = baseOutputPath;
	}

	/**
	 *
	 * @param templatePath 基于项目的路径，如果以/开头，则从classpath开始，否则从当前目录开始
	 */
	public FreeMarkerSupportTool(String templatePath) {
		this(templatePath, null, true);
	}

	public FreeMarkerSupportTool(String templatePath, boolean isProjectBasePath) {
		this(templatePath, null, isProjectBasePath);
	}

	public void generate(String templateName, Map<String, Object> dataMap, String outputPath){
		/*  在整个应用的生命周期中，这个工作你应该只做一次。  */ 
		/*  创建和调整配置。  */
		Writer out = null;
		try {
			if (directory != null) {
                cfg.setDirectoryForTemplateLoading( new File(directory));
            }
			if (clazzForLoadingTemplate != null && pathPrefix != null) {
                cfg.setClassForTemplateLoading(clazzForLoadingTemplate, pathPrefix);
            }
			cfg.setDefaultEncoding("UTF-8");
			cfg.setObjectWrapper(new DefaultObjectWrapper());
		/*  在整个应用的生命周期中，这个工作你可以执行多次  */
		/*  获取或创建模板*/
			Template temp = cfg.getTemplate(templateName);

			if (baseOutputPath != null && !baseOutputPath.isEmpty()) {
                outputPath = baseOutputPath + "/" + outputPath;
            }
			out = new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(outputPath)), "UTF-8");

		/*  将模板和数据模型合并  */
			temp.process(dataMap, out);
			out.flush();
		} catch (Exception e) {
			throw new FreeMarkerException(e);
		} finally {
			if (out != null) {
				try {
					out.close();
				} catch (IOException e) {
					throw new FreeMarkerException(e);
				}
			}
		}
	}

	public String generate(String templateName, Map<String, Object> dataMap){
		ByteArrayOutputStream byteArrayOutputStream = null;
		Writer out = null;
		try {
			/*  在整个应用的生命周期中，这个工作你应该只做一次。  */
			/*  创建和调整配置。  */
			if (directory != null) {
                cfg.setDirectoryForTemplateLoading( new File(directory));
            }
			if (clazzForLoadingTemplate != null && pathPrefix != null) {
                cfg.setClassForTemplateLoading(clazzForLoadingTemplate, pathPrefix);
            }
			cfg.setDefaultEncoding("UTF-8");
			cfg.setObjectWrapper(new DefaultObjectWrapper());
			/*  在整个应用的生命周期中，这个工作你可以执行多次  */
			/*  获取或创建模板*/
			Template temp = cfg.getTemplate(templateName);

			byteArrayOutputStream = new ByteArrayOutputStream();
			out = new OutputStreamWriter(byteArrayOutputStream, "UTF-8");

			/*  将模板和数据模型合并  */
			temp.process(dataMap, out);
			out.flush();
		} catch (Exception e) {
			throw new FreeMarkerException(e);
		} finally {
			if (out != null) {
				try {
					out.close();
				} catch (IOException e) {
					throw new FreeMarkerException(e);
				}
			}
		}

		try {
			return new String(byteArrayOutputStream.toByteArray(), "UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return null;
	}

	public static void main(String[] args) throws IOException, TemplateException {
		FreeMarkerSupportTool fs = new FreeMarkerSupportTool(FreeMarkerSupportTool.class.getResource("/ftl").getFile());
		Map<String, Object> dataMap = new HashMap<>();
		System.out.println(fs.generate("text.ftl", dataMap));

	}


}
